#!/usr/bin/ruby

def run_tests(test_name)
  class_path = "antlr-3.0.1.jar:antlr-2.7.7.jar:stringtemplate.jar:gnujaxp.jar:jcommon-1.0.12.jar:servlet.jar:jfreechart-1.0.8a-experimental.jar:jfreechart-1.0.8a.jar:junit.jar:jfreechart-1.0.8a-swt.jar:itext-2.0.6.jar:."
  puts "\n**********************************************"
  puts "running #{test_name.gsub('@', '').split('_').join(' ')}"
  eval(test_name).each do |test|
    File.open('tmp.gr', 'w') {|f| f.write(test)}
    puts "test:\n\t#{test}"  
    puts `java -cp #{class_path} TestGraphr < tmp.gr`
    File.delete('tmp.gr')
  end
end

@include_tests = [
  "include \"test_include_variables.gr\"; puts a;",
  "include \"test_include_execute.gr\"; puts \"done with the include\";",
  "include \"test_include_function.gr\"; included_function(\"called an included function\");"
  ]

@chart_tests = [
  'data = {"Graphr" => 10, "ruby" => 8, "python" => 5, "java" => 1};
  puts data;
  args = {
    "title" => "Programming languages",
    "type" => "createPieChart",
    "xLabel" => "ignored",
    "yLabel" => "ignored",
    "data" => data,
    "file" => "test_pie.jpg",
    "legend" => true,
    "width" => 450,
    "height" => 450
  };
  puts args; 
  chart(args);'
  ]

@graph_tests = [
  'data = [[1, 3], [3, 4], [5, 5], [10, 6], [12, 10]];
  graph({
    "title" => "Some Random Points",
    "type" => "createScatterPlot",
    "xLabel" => "the x axis",
    "yLabel" => "the y axis",
    "legendLabel" => "random stuff",
    "data" => data,
    "file" => "test_scatter.jpg",
    "legend" => true,
    "width" => 450,
    "height" => 450    
  });
  '
  ]

@puts_tests = [
  "puts \"hello world\";",
  "puts 23;",
  'puts "hello, " + "world!";',
  'puts 3 + 5;'
  ]

@variable_tests = [
  "a = 7; puts a;",
  "a = \"hello from a variable\"; puts a;"
  ]

@math_tests = [
  "a = 3 + 4 + 7; puts a;",
  "a = 3 * 5; puts a;",
  "a = (3 + 4) * 5; puts a;",
  'puts 3 % 2;',
  'puts "hello" % 5;',
  'puts "4" % 2;',
  'puts 5 % "3";'
  ]

@assignment_tests = [
  "test = 234; 				puts test;",
  "test = 1; test += 2; 	puts test;",
  "test = 2; test -= 1; 	puts test;",
  "test = 6; test /= 2; 	puts test;",
  "test = 8; test *= 2; 	puts test;",
  "test = \"some string\"; 	puts test;",
  "test = 2 + 3; puts test;"
  ]
  
@return_tests = [
  "return nil;",
  "return true;",
  "return \"some string\";",
  "return 23;"
  ]

@logical_tests = [
  "foo = true; bar = false; test = foo or bar; 	puts test;",
  "foo = true; bar = false; test = foo || bar; 	puts test;",
  "foo = true; bar = true; test = foo and bar; 	puts test;",
  "foo = true; bar = true; test = foo && bar; 	puts test;",
  "foo = 2; bar = 3; test = foo < bar; 			puts test;",
  "foo = 2; bar = 2; test = foo <= bar; 		puts test;",
  "foo = 3; bar = 2; test = foo > bar; 			puts test;",
  "foo = 3; bar = 3; test = foo >= bar; 		puts test;",
  "foo = 4; bar = 4; test = foo == bar; 		puts test;",
  "foo = 4; bar = 4; test = foo != bar; 		puts test;",
  'puts !true;',
  'a = false; puts !a;',
  't = 1; if (t == 1) {puts "hi";}'
  ]

@function_tests = [
  'def myfun() {a = "test"; puts a;} myfun();',
  "def myfun(arg1, arg2) {puts arg1; puts arg2;} myfun(\"hello\", \"world\");",
  "def myfun() {puts \"hello from function with no arguments\";} myfun();",
  "def myfun(arg) {puts arg;} myfun(\"a function with one argument\");",
  'def myfun() {puts "in function"; return 3; puts "this should NOT output";} a = myfun(); puts "returned value: " + a;',
  'def myfun() {puts "in function"; return 3; puts "this should NOT output";} puts myfun() + 3;',
  'def myfun(arg) {puts "in function"; return arg + 2; puts "this should not print!";} puts "returned value: " + myfun(2);'
  ]

@temp_func_tests = [
  'def myfun() {if (true) {return "hello";} a = 10; puts "this should NOT output" + a;} puts myfun();'
  ] 

@loop_tests = [
  "i = 3; for (i; i < 5; i += 1) { puts i; puts \"hello\";}",
  "for (i = 2; i < 5; i += 1) {puts i; puts \"hi from second\";}"
  ]

@while_tests = [
  "i = 0; while (i < 3) {puts i; i += 1;}",
  "t = true; while (t) {puts t; t = false;}"
  ]

@foreach_tests = [
  'foreach (i in ["hello", "world"]) {puts i;} puts "done";'
  ]

@array_tests = [
  'a = []; puts a;',
  "puts [2, 1, 3, 9, 10];",
  "a = [2, 1, 3]; puts a;",
  "a = [\"test\", \"stuff\"]; puts a;",
  "a = [\"test\", \"stuff\"]; puts a[1];",
  "a = [\"test\", \"stuff\"]; a[0] = \"hello world\"; puts a[0];",
  'a = ["foo", "bar"]; a += [3, 2]; puts a;'
  ]

@if_tests = [
  "a = true; if (a) {puts \"a was true\";}",
  "a = false; if (a) {puts \"we shouldn't get here\";} else {puts \"a was false\";}"
  ]

@hash_tests = [
  'a = {}; a["test"] = "hello world"; puts a;',
  "a = {\"asdf\" => 3, \"foo\" => \"bar\"}; puts a;",
  "a = {\"asdf\" => 3, \"foo\" => \"bar\"}; puts a[\"foo\"];",
  "a = {\"asdf\" => 3, \"foo\" => \"bar\"}; a[\"foo\"] = \"hello world\"; puts a[\"foo\"];",
  "a = \"hello\"; b = {\"foo\" => 3, \"bar\" => a}; puts b;",
  'a = {"foo" => 3, "bar" => 2}; foreach(key in a) {puts key;}'
  ]

@file_tests = [
  "a = read_file(\"test.txt\"); puts a;",
  "foreach (line in read_file(\"test.txt\")) {puts line;}",
  "a = read_file(\"test.txt\"); a[2] = \"modified line\"; puts write_file(\"modified.txt\", a, \"w\");"
   ]

@string_function_tests = [
  'puts length("hello");',
  'foreach (sub in split("this, is, a, test string", ", ")) {puts sub;}',
  'a = "this, is, a, test string"; foreach (sub in split(a, ", ")) {puts sub;}',
  'puts substring("hello world", 0, 3);',
  'a = "hello, world"; puts substring(a, 5, length(a));'
  ]

@scope_tests = [
  'foo = "test"; def bar() {puts foo;} bar();',
  'foo = "test"; puts foo;',
  'foo = "test"; if (true) {foo = "bar";} puts foo;',
  'foo = "test"; def bar() {foo = "bar"; puts foo;} bar(); puts foo;'
  ]

@length_tests = [
  'a = "hello"; puts length(a);',
  'a = [1, 2, 2]; puts length(a);',
  'a = {"foo" => 2, "bar" => 2}; puts length(a);'
  ]

@contains_tests = [
  'a = {"foo" => 3}; puts contains(a, "foo");',
  'a = {"bar" => 3}; puts contains(a, "foo");'
  ]
  
if ARGV.first
  run_tests("@" << ARGV.first)
else
  instance_variables.select {|var| var =~ /.*_tests$/}.each do |tests|
    run_tests(tests)
  end
end